home *** CD-ROM | disk | FTP | other *** search
- /* Listing 6. TOPDOWN3.C - Expression Evaluator */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include "lex.h"
-
- int statement ( void );
- int expression_and_predicate ( void );
- int mult_expr_and_predicate ( void );
- int factor ( void );
- void error (char *fmt,...);
-
- #ifdef PTRACE
- static int Rdepth = 0;
- int rdepth(void) {return( Rdepth * 8 );}
- # define trace(name) printf("%*s%s\n", Rdepth++ * 8, "", name)
- # define untrace(name) (--Rdepth)
- #else
- # define trace(name) /* empty */
- # define untrace(name) /* empty */
- #endif
- /*----------------------------------------------------------------------*/
- int statement( void )
- {
- /* statement->expression SEMI LP SEMI NUMBER
- */
-
- int value;
-
- trace("statement");
-
- if( match(LP) || match(SEMI) || match(NUMBER) )
- {
- value = expression_and_predicate();
-
- if( match(SEMI) ) advance();
- else error("Inserting missing semicolon.");
-
- return value;
- }
- else
- {
- error("Illegal expression\n");
- return 0;
- }
-
- untrace("statement");
- }
- /*----------------------------------------------------------------------*/
- int expression_and_predicate( void )
- {
- /* expression->mult_expr predicate LP NUMBER
- * expression->(epsilon) RP SEMI
- *
- * Modified to incorporate the predicate productions and also
- * to eliminate the tail recursion in the original predicate();
- */
-
- int value; /* accumulated value of subexpression */
-
- trace("expression_and_predicate");
-
- if( match(RP) || match(SEMI) )
- ; /* epsilon */
-
- else if( !(match(LP) || match(NUMBER)) )
- error( "expression expected\n" );
- else
- {
- value = mult_expr_and_predicate();
-
- /* predicate->PLUS mult_expr predicate PLUS
- * predicate->MINUS mult_expr predicate MINUS
- * predicate->(epsilon) RP SEMI
- */
-
- while( 1 )
- {
- if( match(RP) || match(SEMI) )
- break; /* epsilon */
-
- else if( match(PLUS) ){ advance();
- value += mult_expr_and_predicate();
- }
- else if( match(MINUS)){ advance();
- value -= mult_expr_and_predicate();
- }
- else
- {
- error("operator or statement-terminator expected\n");
- break;
- }
- }
- }
-
- untrace("expression_and_predicate");
- return value;
- }
- /*----------------------------------------------------------------------*/
- int mult_expr_and_predicate( void )
- {
- /* mult_expr->factor mult_predicate LP NUMBER
- *
- * Modified to eliminate chain to mult_predicate() and also
- * eliminate tail recursion in mult_predicate();
- */
-
- static int value; /* value of subexpression */
-
- trace("mult_expr_and_predicate");
-
- if( !(match(LP) || match(NUMBER)) )
- error( "Expected number identifier or open parenthesis\n" );
- else
- {
- value = factor();
-
- /* mult_predicate->STAR factor mult_predicate STAR
- * mult_predicate->SLASH factor mult_predicate SLASH
- * mult_predicate->(epsilon) RP PLUS MINUS SEMI
- */
-
- while( 1 )
- {
- if( match(RP) || match(PLUS) || match(MINUS) || match(SEMI) )
- break; /* epsilon */
-
- else if( match(STAR) ) { advance(); value *= factor() ; }
- else if( match(SLASH)) { advance(); value /= factor() ; }
- else
- {
- error("operator expected\n");
- break;
- }
- }
- }
-
- return value;
- untrace("mult_expr_and_predicate");
- }
- /*----------------------------------------------------------------------*/
- int factor( void )
- {
- /* factor->NUMBER NUMBER
- * factor->LP expression RP LP
- *
- * Returns value of NUMBER or subexpression
- */
-
- int value;
-
- trace( "factor" );
-
- if( match(NUMBER) )
- {
- value = atoi(yytext);
- advance();
- }
- else if( match(LP) )
- {
- advance();
- value = expression_and_predicate();
-
- if( match(RP) ) advance();
- else error("Inserting missing right parenthesis.");
- }
- else
- error("Number or parenthesized subexpression expected\n");
-
- untrace( "factor" );
- return value;
- }
- /*----------------------------------------------------------------------*/
- void error( char *fmt, ... )
- {
- va_list args;
- va_start( args, fmt );
- vfprintf( stderr, fmt, args );
- va_end( args );
- }
- /*----------------------------------------------------------------------*/
- int main()
- {
-
- printf("Enter Expression: ");
- printf("= %d\n", statement() );
-
- return 0;
- }